package nl.rug.ai.believer.ui;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import nl.rug.ai.believer.model.Core;

/**
 * This is a simple command line interface for the Believer program
 * @author S1849700
 *
 */
public class CommandLineInterface {

	private boolean quit = false;
	
	/**
	 * Main method, this one will start up a command line reader, load the config, set up the rest
	 * of the program, and parse new commands.
	 */
	public void run() {
		BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		System.out.println("Welcome to Believer\n");
		loadConfig();
		while (!quit) {
			String nextLine;
			try {
				nextLine = reader.readLine();
			}
			catch (IOException ioe) {
				System.out.println("Fatal error while reading input, terminating...");
				return;
			}
			parse(nextLine);
		}
	}

	/**
	 * Method used to parse new incoming commands.
	 * @param input - the new command
	 */
	private void parse(String input) {
		Core core = Core.getCore();
		String myInput = input.toLowerCase().trim();
		try {
			if (input.equals("help")) {
				printHelp();
			} else if (myInput.equals("list worlds")) {
				System.out.println(core.listWorlds());
			} else if (myInput.equals("list relations")) {
				System.out.println(core.listRelations());
			} else if (myInput.equals("list agents")) {
				System.out.println(core.listAgents());
			} else if (myInput.equals("list equivalence classes")) {
				System.out.println(core.listEquivalenceClasses());
			} else if (myInput.startsWith("verbose")) {
				if (myInput.substring(8).trim().equals("on")){
					core.setVerbose(true);
					System.out.println("Verbose mode on.");
				} else {
					core.setVerbose(false);
					System.out.println("Verbose mode off.");
				}
			} else if (myInput.startsWith("read file")) {
				if (core.readFile(input.substring(10).trim())) {
					System.out.println("File was read successfully.");
				}
				else {
					System.out.println("Failed to read file.");
				}
			} else if (myInput.startsWith("evaluate")) {
				
					if (core.evaluate(input.substring(9).trim())) {
						System.out.println("This formula evaluates as true");
					} else {
						System.out.println("This formula evaluates as false");
					}
				
			} else if(myInput.equals("quit") || myInput.equals("exit")) {
				quit = true;
				System.out.println("Goodbye");
			} else {
				System.out.println("Unknown command. See 'help' for all available commands");
			}
		}
		catch (RuntimeException re) {
			System.out.println("Error: " + re.getMessage());
		}
		System.out.println(""); // add an empty line.
	}
	
	/**
	 * support method which prints all available commands.
	 */
	private void printHelp(){
		System.out.println("Welcome to Believer\n");
		System.out.println("The following commands are available:");
		System.out.println("help -- this command");
		System.out.println("list worlds -- lists all worlds");
		System.out.println("list relations -- lists all relations");
		System.out.println("list agents -- lists all agents");
		System.out.println("list equivalence classes -- lists all equivalence classes");
		System.out.println("verbose on/off -- sets verbose on or off");
		System.out.println("read file <file> -- reads a specified file");
		System.out.println("evaluate <formula> -- evaluates a specific formula/statement");
		System.out.println("exit -- exits the application");
		System.out.println("quit -- alias of exit");
	}
	
	/**
	 * support method which is used to initially load the configuration file.
	 */
	private void loadConfig() {
		try {
		Core.getCore().reloadConfig();
		}
		catch (RuntimeException rte) {
			System.out.println("Error loading config, using default settings.");
			System.out.println("Error was: " + rte.getMessage());
		}
	}
	
	/**
	 * main point of entry for the program.
	 * @param args -- none
	 */
	public static void main(String[] args) {
		CommandLineInterface cli = new CommandLineInterface();
		cli.run();
	}
}
